﻿using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.ComponentModel;
using System.Globalization;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Controls.Primitives;
using System.Windows.Input;
using System.Windows.Shapes;
using ExtendedGrid.Base;
using ExtendedGrid.Classes;
using Microsoft.Windows.Controls;
using Microsoft.Windows.Controls.Primitives;

namespace ExtendedGrid.ExtendedGridControl
{
    public sealed class ExtendedDataGrid : CopyDataGrid
    {
        #region Members

        private static readonly Uri DataGriduri = new Uri("/ExtendedGrid;component/Styles/DataGrid.Generic.xaml",
                                                          UriKind.Relative);

        private readonly ResourceDictionary _datagridStyle = new ResourceDictionary {Source = DataGriduri};

        #endregion

        #region Constructors

        public ExtendedDataGrid()
        {
            AddResouces();
            (Items.SortDescriptions as INotifyCollectionChanged).CollectionChanged += SortDescriptionsCollectionChanged;
            Sorting += DataGridStandardSorting;
            PreviewKeyDown += ExtendedDataGridPreviewKeyDown;
        }

        #endregion

        #region "Attached Properties"

        public Boolean AllowUserToCopy
        {
            get { return (Boolean)GetValue(AllowUserToCopyProperty); }
            set { SetValue(AllowUserToCopyProperty, value); }
        }

        public static readonly DependencyProperty AllowUserToCopyProperty = DependencyProperty.Register(
          "AllowAdvancedCopy", typeof(Boolean), typeof(ExtendedDataGrid), new PropertyMetadata(true));

        public Boolean HideColumnChooser
        {
            get { return (Boolean) GetValue(HideColumnChooseProperty); }
            set { SetValue(HideColumnChooseProperty, value); }
        }

        public static readonly DependencyProperty HideColumnChooseProperty = DependencyProperty.Register(
            "HideColumnChooser", typeof (Boolean), typeof (ExtendedDataGrid), new PropertyMetadata(false));

        public Boolean ShowSortOrder
        {
            get { return (Boolean)GetValue(ShowSortOrderProperty); }
            set { SetValue(ShowSortOrderProperty, value); }
        }

        public static readonly DependencyProperty ShowSortOrderProperty = DependencyProperty.Register(
            "ShowSortOrder", typeof(Boolean), typeof(ExtendedDataGrid), new PropertyMetadata(false));

        #endregion

        #region Methods

        private void AddResouces()
        {
            if (!UriParser.IsKnownScheme("pack"))
                UriParser.Register(new GenericUriParser(GenericUriParserOptions.GenericAuthority), "pack", -1);


            //Datagrid
            if (!Resources.MergedDictionaries.Contains(_datagridStyle))
                Resources.MergedDictionaries.Add(_datagridStyle);
        }

        public void ClearFilter(string columnName)
        {
            AutoFilterHelper.RemoveAllFilter(this, columnName);
            DataGridColumnHeader header =
                FindControls.GetColumnHeaderFromColumn(Columns[GetColumnIndex(Columns, columnName)]);
            if (header != null)
            {
                var popUp = FindControls.FindChild<Popup>(header, "popupDrag");
                if (popUp != null)
                {
                    popUp.Tag = "False";
                }
            }
        }

        private static int GetColumnIndex(IEnumerable<DataGridColumn> columns, string filedName)
        {
            int index = 0;
            foreach (DataGridColumn col in columns)
            {
                if (col.SortMemberPath == filedName)
                {
                    return index;
                }
                index++;
            }

            return index;
        }

        public void ExportToExcel(string workSheetName, string fullFilePath, bool toOpen)
        {
            try
            {
                //Select all rows 
                Focus();
                SelectAll();
                //Copy the entire grid
                ClipboardCopyMode = DataGridClipboardCopyMode.IncludeHeader;
                ApplicationCommands.Copy.Execute(null, this);
                Clipboard.GetText();
                ExportToExcelService.CreateExcelFromClipboard(workSheetName, fullFilePath, toOpen);
                UnselectAll();
            }
            catch (Exception)
            {
                UnselectAll();
                throw;
            }

        }

        public void ExportToPdf(string workSheetName, string fullFilePath, bool toOpen)
        {
            try
            {
                //Select all rows 
                Focus();
                SelectAll();
                //Copy the entire grid
                ClipboardCopyMode = DataGridClipboardCopyMode.IncludeHeader;
                ApplicationCommands.Copy.Execute(null, this);
                Clipboard.GetText();
                ExportToExcelService.CreatePdfFromClipboard(workSheetName, fullFilePath, toOpen);
                UnselectAll();
            }
            catch (Exception)
            {
                UnselectAll();
                throw;
            }

        }

        public void ExportToPdf(string workSheetName, string fullFilePath, ExcelTableStyle tableStyle, bool toOpen)
        {
            try
            {
                //Select all rows 
                Focus();
                SelectAll();
                //Copy the entire grid
                ClipboardCopyMode = DataGridClipboardCopyMode.IncludeHeader;
                ApplicationCommands.Copy.Execute(null, this);
                Clipboard.GetText();
                ExportToExcelService.CreatePdfFromClipboard(workSheetName, fullFilePath, tableStyle, toOpen);
                UnselectAll();
            }
            catch (Exception)
            {
                UnselectAll();
                throw;
            }

        }

        public void ExportToCsv(string workSheetName, string fullFilePath, bool toOpen)
        {
            try
            {
                //Select all rows 
                Focus();
                SelectAll();
                //Copy the entire grid
                ClipboardCopyMode = DataGridClipboardCopyMode.IncludeHeader;
                ApplicationCommands.Copy.Execute(null, this);
                Clipboard.GetText();
                ExportToExcelService.CreateCsvFromClipboard(workSheetName, fullFilePath, toOpen);
                UnselectAll();
            }
            catch (Exception)
            {
                UnselectAll();
                throw;
            }

        }

        public void ExportToExcel(string workSheetName, string fullFilePath, ExcelTableStyle tableStyle, bool toOpen)
        {
            try
            {
                //Select all rows 
                Focus();
                SelectAll();
                //Copy the entire grid
                ClipboardCopyMode = DataGridClipboardCopyMode.IncludeHeader;
                ApplicationCommands.Copy.Execute(null, this);
                Clipboard.GetText();
                ExportToExcelService.CreateExcelFromClipboard(workSheetName, fullFilePath, tableStyle, toOpen);


                UnselectAll();
            }
            catch (Exception)
            {
                UnselectAll();
                throw;
            }

        }

        #endregion

        #region Events

        void ExtendedDataGridPreviewKeyDown(object sender, KeyEventArgs e)
        {

            if (!AllowUserToCopy)
            {
                if (e.Key == Key.C)
                {
                    if (Keyboard.IsKeyDown(Key.LeftCtrl) || (Keyboard.IsKeyDown(Key.RightCtrl)))
                    {
                        e.Handled = true;
                    }
                }
            }
        }

        private void SortDescriptionsCollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
        {
            // clear all the headers of sort order
            foreach (DataGridColumn column in Columns)
            {
                string sortPath = SortHelpers.GetSortMemberPath(column);
                if (sortPath != null)
                {
                    var sortOrder1 = new Path();
                    DataGridColumnHeader header = FindControls.GetColumnHeaderFromColumn(column, this);
                    if (header != null)
                    {
                        var popUp = FindControls.FindChild<Popup>(header, "popupDrag");
                        if (popUp != null)
                        {
                            sortOrder1 = FindControls.FindChild<Path>(header, "SortArrow");
                        }
                        if(sortOrder1!=null)
                        {
                            sortOrder1.Tag = null;
                        }
                    }
                }
            }

            // add sort order 
            int sortIndex = 0;
            foreach (SortDescription sortDesc in Items.SortDescriptions)
            {


                   sortIndex++;
                    var sortOrder = new Path();
                    var txtSortOrder = new TextBlock();

                    DataGridColumnHeader header = FindControls.GetColumnHeaderFromColumn(Columns[GetColumnIndex(Columns,sortDesc.PropertyName)], this);
                    if (header != null)
                    {
                        var popUp = FindControls.FindChild<Popup>(header, "popupDrag");
                        if (popUp != null)
                        {
                            sortOrder = FindControls.FindChild<Path>(header, "SortArrow");
                            txtSortOrder = FindControls.FindChild<TextBlock>(header, "txtSortOrder");
                        }
                    }
                    if (sortDesc.PropertyName == SortHelpers.GetSortMemberPath(Columns[GetColumnIndex(Columns, sortDesc.PropertyName)]))
                    {
                        
                       
                        if (Items.SortDescriptions.Count>1&&ShowSortOrder)
                        {
                        
                            if (sortOrder != null)
                            {
                                sortOrder.Tag = "True";
                                if(txtSortOrder!=null)
                                {
                                    txtSortOrder.Text = sortIndex.ToString(CultureInfo.InvariantCulture);
                                }
                            }
                        }
                    }
                    else
                    {
                        sortOrder.Tag = null;
                    }
                }
              
            
        }

        private void DataGridStandardSorting(object sender, DataGridSortingEventArgs e)
        {
           

            string sortPropertyName = SortHelpers.GetSortMemberPath(e.Column);
            if (!string.IsNullOrEmpty(sortPropertyName))
            {
                // sorting is cleared when the previous state is Descending
                if (e.Column.SortDirection.HasValue && e.Column.SortDirection.Value == ListSortDirection.Descending)
                {
                    int index = SortHelpers.FindSortDescription(Items.SortDescriptions, sortPropertyName);
                    if (index != -1)
                    {
                        e.Column.SortDirection = null;

                        // remove the sort description
                        Items.SortDescriptions.RemoveAt(index);
                        Items.Refresh();

                        if ((Keyboard.Modifiers & ModifierKeys.Shift) != ModifierKeys.Shift)
                        {
                            // clear any other sort descriptions for the multisorting case
                            Items.SortDescriptions.Clear();
                            Items.Refresh();
                        }

                        // stop the default sort
                        e.Handled = true;
                    }
                }
            }
        }

        #endregion
    }
}
